using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Jeffrey.XFramework;
using Jeffrey.XFramework.XCrawl;

namespace Jeffrey.Xuthus
{
    public partial class XProcessorsForm : Form
    {
        public XProcessorsForm(XController xc, CrawlController cc)
        {
            m_XController     = xc;
            m_CrawlController = cc;

            InitializeComponent();
        }

        public void InitializeStuffs()
        {
            CreateChainTree();
        }

        public void Disable()
        {
            ProcessorsConfigTableLayoutPanel.Enabled = false;
            XProcessorsTreeView.Enabled = false;
        }

        public void Enable()
        {
            ProcessorsConfigTableLayoutPanel.Enabled = true;
            XProcessorsTreeView.Enabled = true;
        }

        private void addProcessorToolStripMenuItem_Click(Object sender, EventArgs e)
        {
            XProcessorsTabControl.SelectedTab = ProcessorsTabConfig;
        }

        private void ProcessorPathButton_Click(Object sender, EventArgs e)
        {
            OpenFileDialog opd = new OpenFileDialog();
            opd.Filter = "Dynamic link library(*.dll)|*.dll";
            opd.ValidateNames = true;

            if (DialogResult.OK == opd.ShowDialog() &&
                opd.FileName != String.Empty)
            {
                ProcessorLocationTextBox.Text = opd.FileName;   
            }
        }

        public void CreateChainTree()
        {
            foreach (TreeNode tn in XProcessorsTreeView.Nodes[0].Nodes)
                tn.Nodes.Clear();
            /*
             * the main loop of tree creating...
             */
            foreach (Processor proc in m_CrawlController.UriProcessChain)
            {
                TreeNode tn = XProcessorsTreeView.Nodes[0].Nodes[proc.Chain.Name.ToString()].Nodes.Add(proc.Name, proc.Name, 6, 6);
                if (proc.Filter != null)
                {
                    TreeNode filter = XProcessorsTreeView.Nodes[0].Nodes[proc.Chain.Name.ToString()].Nodes[proc.Name].Nodes.Add(proc.Filter.Name, proc.Filter.Name, 7, 7);
                    filter.ContextMenuStrip = ProcessorContextMenuStrip;
                    if ( proc.Filter.Description != null &&
                         proc.Filter.Description != String.Empty
                       )
                        filter.ToolTipText = proc.Filter.Description;
                }
                if( proc.Description != null &&
                    proc.Description != String.Empty
                   )
                    tn.ToolTipText = proc.Description;

                tn.ContextMenuStrip = ProcessorContextMenuStrip;
            }
        }

        private void FilterPathButton_Click(Object sender, EventArgs e)
        {
            OpenFileDialog opd = new OpenFileDialog();
            opd.Filter = "Dynamic link library(*.dll)|*.dll";
            opd.ValidateNames = true;

            if (DialogResult.OK == opd.ShowDialog() &&
                opd.FileName != String.Empty)
            {
                FilterLocationTextBox.Text = opd.FileName;
            }
        }

        private void FilterCheckBox_CheckedChanged(Object sender, EventArgs e)
        {
            EnableFilterAdding(FilterCheckBox.Checked);
        }

        private void EnableFilterAdding(Boolean enable)
        {
            FilterClassNameTextBox.Enabled   = enable;
            FilterDescriptionTextBox.Enabled = enable;
            FilterNameTextBox.Enabled        = enable;
            FilterPathButton.Enabled         = enable;
        }

        private void ProcessorAddButton_Click(Object sender, EventArgs e)
        {
            if (ChainSelectComboBox.SelectedItem == null ||
                ProcessorNameTextBox.Text == String.Empty ||
                ProcessorClassNameTextBox.Text == String.Empty ||
                ProcessorLocationTextBox.Text == String.Empty ||
                (FilterCheckBox.Checked &&
                 (FilterNameTextBox.Text == String.Empty ||
                FilterClassNameTextBox.Text == String.Empty ||
                FilterLocationTextBox.Text == String.Empty
                 )
                )
               )
            {
                MessageBox.Show("Please complete the Processor's Infomation.", "Information Absent", MessageBoxButtons.OK, 
                                                                                                    MessageBoxIcon.Error);
            }
            else
            {
                Boolean succeed = true;
                String ChainName = ChainSelectComboBox.SelectedItem as String;

                ProcessorInfo proinfo = new ProcessorInfo();

                proinfo.Name        = ProcessorNameTextBox.Text;
                proinfo.Description = ProcessorDescriptionTextBox.Text;
                proinfo.ClassName   = ProcessorClassNameTextBox.Text;
                proinfo.Path        = ProcessorLocationTextBox.Text;

                if (FilterCheckBox.Checked)
                {
                    ProcessorInfo filter = new ProcessorInfo();
                    filter.Name = FilterNameTextBox.Text;
                    filter.Description = FilterDescriptionTextBox.Text;
                    filter.ClassName = FilterClassNameTextBox.Text;
                    filter.Path = FilterLocationTextBox.Text;

                    if (!m_XController.CreateFilter(filter))
                    {
                        return;
                    }

                    proinfo.Attachedfilter = filter.Name;
                }

                switch (ChainName)
                {
                    case "PreFetchChain": succeed = m_XController.AddProcessor(proinfo, ProcessorChain.ProcessorChainName.PreFetchChain);   break;
                    case "FetchChain": succeed = m_XController.AddProcessor(proinfo, ProcessorChain.ProcessorChainName.FetchChain);         break;
                    case "PostFetchChain": succeed = m_XController.AddProcessor(proinfo, ProcessorChain.ProcessorChainName.PostFetchChain); break;
                    case "ExtractChain": succeed = m_XController.AddProcessor(proinfo, ProcessorChain.ProcessorChainName.ExtractChain);     break;
                    case "StoreChain": succeed = m_XController.AddProcessor(proinfo, ProcessorChain.ProcessorChainName.StoreChain);         break;
                    default: succeed = false; break;
                }

                if (succeed)
                {
                    MessageBox.Show("Processor " + proinfo.Name + " is Created.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    CreateChainTree();
                }
                else
                {
                    MessageBox.Show("Processor " + proinfo.Name + "'s creation failed!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void XProcessorsTreeView_MouseDown(Object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                XProcessorsTreeView.SelectedNode = XProcessorsTreeView.GetNodeAt(e.X, e.Y);
            }
        }

        private void deleteToolStripMenuItem_Click(Object sender, EventArgs e)
        {
            TreeNode tn = XProcessorsTreeView.SelectedNode;

            if (tn.Level == 3)
                m_XController.DeleteTreeItem(tn.Parent.Text, true);
            if (tn.Level == 2)
                m_XController.DeleteTreeItem(tn.Text, false);

            CreateChainTree();
        }

        private void deleteChainToolStripMenuItem_Click(Object sender, EventArgs e)
        {
            TreeNode tn = XProcessorsTreeView.SelectedNode;

            foreach (TreeNode tr in tn.Nodes)
            {
                m_XController.DeleteTreeItem(tr.Text, false);
            }

            CreateChainTree();
        }

        private void ProcessorContextMenuStrip_Opening(Object sender, CancelEventArgs e)
        {
            TreeNode tn = XProcessorsTreeView.SelectedNode;
            if (tn.Level == 2)
            {
                enableToolStripMenuItem.Checked = m_CrawlController.GetProcessorFromChain(tn.Text).Enabled;
            }
            if (tn.Level == 3)
            {
                enableToolStripMenuItem.Checked = m_CrawlController.GetFilterByName(tn.Text).Enabled;
            }
        }

        private void enableToolStripMenuItem_Click(Object sender, EventArgs e)
        {
            TreeNode tn = XProcessorsTreeView.SelectedNode;
            if (tn.Level == 2)
            {
                m_XController.DisableItem(tn.Text, !enableToolStripMenuItem.Checked, false);
            }
            else
            {
                m_XController.DisableItem(tn.Text, !enableToolStripMenuItem.Checked, true);
            }
        }

        private XController     m_XController;
        private CrawlController m_CrawlController;
    }
}